package Factory;

import Model.DrawModel.CalPoint;
import Model.SurroundModel.*;
import Model.DrawModel.HistoricalTrack;
import Model.IntermittentCommunicationModel.BaseShip;
import Model.check_inside_util.CheckSurround;
import Service.SurroundService.*;
import Service.TransformService.TransformService;

import java.util.ArrayList;
import java.util.List;

/**
 * 参数转换工具类
 * @author dingN
 * @date 2022/06/22
 */
public class ParamChangeUtil {

    // 绘图信息
    public static ArrayList<CalPoint> TargetList = new ArrayList<>();        // 绘制目标队列所用list
    public static ArrayList<CalPoint> ShipsList = new ArrayList<>();    // 绘制船队轨迹所用list
    public static ArrayList<CalPoint> VirtualTargets = new ArrayList<>();
    public static CalPoint Center = new CalPoint();                      // 绘制目标队列中心点所用Point
    public static ArrayList<HistoricalTrack> HistoricalShipsList = new ArrayList<>();  //船队历史轨迹
    public static List<Double> shipMinDis = new ArrayList<>(); // 表格数据
    public static List<Double> shipEvDis = new ArrayList<>(); // 表格数据
    public static List<Double> surround = new ArrayList<>(); // 包围情况表格数据

    public static List<Double> getSurround() {
        return surround;
    }

    public ParamChangeUtil() {

    }

    public ParamChangeUtil(
            ArrayList<CalPoint> targetList,
            ArrayList<CalPoint> shipsList,
            ArrayList<CalPoint> virtualtargets ,
            CalPoint center,
            ArrayList<HistoricalTrack> historicalShipsList
    ) {
        TargetList = targetList;
        ShipsList = shipsList;
        VirtualTargets =virtualtargets;
        Center = center;
        HistoricalShipsList = historicalShipsList;
    }

    public void SetChartData() {

    }

    /**
     * 提取目标数据 到 点列表
     * @param target    目标
     * @param calPointList 点列表
     */
    public void ChangeTargetsToPointList(
            ArrayList<Target> target,
            ArrayList<CalPoint> calPointList
    ) {
        calPointList.clear();
        for (Target tt : target) {
            CalPoint p = new CalPoint();
            p.x = tt.x;
            p.y = tt.y;
            calPointList.add(p);
        }
    }

    /**
     * 提取目标数据 到 点列表
     * @param target    目标
     * @param calPointList 点列表
     */
    public void ChangeTargetSecondToPointList(
            ArrayList<TargetSecond> target,
            ArrayList<CalPoint> calPointList
    ) {
        calPointList.clear();
        for (TargetSecond tt : target) {
            CalPoint p = new CalPoint();
            p.x = tt.x;
            p.y = tt.y;
            calPointList.add(p);
        }
    }



    /**
     * 保存领航船数据
     * @param leaderShip    目标
     * @param calPointList 点列表
     */
    public void SaveLeaderData(
            BaseShip leaderShip,
            ArrayList<CalPoint> calPointList
    ) {
        calPointList.clear();
//        for (Target tt : target) {
            CalPoint p = new CalPoint();
            p.x = leaderShip.ηMatrix.get(0,0);
            p.y = leaderShip.ηMatrix.get(1,0);
            calPointList.add(p);
//        }
    }

    /**
     * 提取目标中心数据
     * @param target 目标
     * @param center 中心
     */
    public void ChangeTargetToCenter(
            Target target,
            CalPoint center
    ) {
        center.x = target.x0;
        center.y = target.y0;
    }

    /**
     * 改变中心第二目标
     *
     * @param target 目标
     * @param center 中心
     */
    public void ChangeSecondTargetToCenter(
            TargetSecond target,
            CalPoint center
    ) {
        center.x = target.x0;
        center.y = target.y0;
    }

    /**
     * 保存船队历史数据
     * @param ships               船只
     * @param time                时间
     * @param HistoricalShipsList 历史船舶名单
     */
    public void SaveHistoryData(
            ArrayList<Ship> ships,
            double time,
            ArrayList<HistoricalTrack> HistoricalShipsList
    ) {
        HistoricalTrack ht = new HistoricalTrack();
        ht.time = time;
        ht.HistoricalShips = new ArrayList<CalPoint>();
        for (Ship ship : ships) {
            CalPoint p = new CalPoint();
            p.x = ship.x;
            p.y = ship.y;
            ht.HistoricalShips.add(p);
        }
        HistoricalShipsList.add(ht);
    }

    /**
     * 保存不同数量历史数据
     *
     * @param ships               船只
     * @param time                时间
     * @param HistoricalShipsList 历史船舶名单
     */
    public void SaveSamplingHistoryData(
            ArrayList<ShipSampling> ships,
            double time,
            ArrayList<HistoricalTrack> HistoricalShipsList
    ) {
        HistoricalTrack ht = new HistoricalTrack();
        ht.time = time;
        ht.HistoricalShips = new ArrayList<CalPoint>();
        for (ShipSampling ship : ships) {
            CalPoint p = new CalPoint();
            p.x = ship.x;
            p.y = ship.y;
            ht.HistoricalShips.add(p);
        }
        HistoricalShipsList.add(ht);
    }

    /**
     * 保存二阶船队历史数据
     *
     * @param ships               船只
     * @param time                时间
     * @param HistoricalShipsList 历史船舶名单
     */
    public void SaveSecondHistoryData(
            ArrayList<ShipSecond> ships,
            double time,
            ArrayList<HistoricalTrack> HistoricalShipsList
    ) {
        HistoricalTrack ht = new HistoricalTrack();
        ht.time = time;
        ht.HistoricalShips = new ArrayList<CalPoint>();
        for (ShipSecond ship : ships) {
            CalPoint p = new CalPoint();
            p.x = ship.x;
            p.y = ship.y;
            ht.HistoricalShips.add(p);
        }
        HistoricalShipsList.add(ht);
    }

    /**
     * 保存船队历史数据:队列变化
     *
     * @param Ships               船只
     * @param time                时间
     * @param HistoricalShipsList 历史船舶名单
     */
    public void SaveTransHistoryData(
            Ship[][] Ships,
            double time,
            ArrayList<HistoricalTrack> HistoricalShipsList
    ) {
        HistoricalTrack ht = new HistoricalTrack();
        ht.time = time;
        ht.HistoricalShips = new ArrayList<CalPoint>();
        for (int i = 1; i < Ships.length; i++) {
            CalPoint p = new CalPoint();
            p.x = Ships[i][0].x;
            p.y = Ships[i][0].y;
            ht.HistoricalShips.add(p);
        }
        HistoricalShipsList.add(ht);
    }


    /**
     * 保存船队历史数据:间歇通信
     * @param ships               船只
     * @param time                时间
     * @param HistoricalShipsList 历史船舶名单
     */
    public void SaveHistoryData(
            List<BaseShip> ships,
            double time,
            ArrayList<HistoricalTrack> HistoricalShipsList
    ) {
        HistoricalTrack ht = new HistoricalTrack();
        ht.time = time;
        ht.HistoricalShips = new ArrayList<CalPoint>();
        for (int i = 0; i < ships.size(); i++) {
            BaseShip ship = ships.get(i);
            CalPoint p = new CalPoint();
            p.x = ship.ηMatrix.get(0, 0);
            p.y = ship.ηMatrix.get(1, 0);
            ht.HistoricalShips.add(p);
        }
        HistoricalShipsList.add(ht);
    }

    /**
     * 保存船舶当前位置数据
     *
     * @param ShipsList 船舶名单
     * @param ships     船只
     */
    public void SaveShipData(
            ArrayList<CalPoint> ShipsList,
            ArrayList<Ship> ships
    ) {
        ShipsList.clear();
        //int i = 1 ;
        for (Ship ship : ships) {
            CalPoint p = new CalPoint();
            p.x = ship.x;
            p.y = ship.y;
            ShipsList.add(p);
        }
    }

    /**
     * 保存船舶当前位置数据
     *
     * @param ShipsList 船舶名单
     * @param ships     船只
     */
    public void SaveShipData(
            ArrayList<CalPoint> ShipsList,
            List<BaseShip> ships
    ) {
        ShipsList.clear();
        //int i = 1 ;
        for (int i = 1; i < ships.size(); i++) {
            BaseShip ship = ships.get(i);
            CalPoint p = new CalPoint();
            p.x = ship.ηMatrix.get(0, 0);
            p.y = ship.ηMatrix.get(1, 0);
            ShipsList.add(p);
        }
    }


    /**
     * 保存据
     *
     * @param ShipsList 船舶名单
     * @param ships     船只
     */
    public void SaveSecondShipData(
            ArrayList<CalPoint> ShipsList,
            List<ShipSecond> ships
    ) {
        ShipsList.clear();
        for (int i = 0; i < ships.size(); i++) {
            ShipSecond ship = ships.get(i);
            CalPoint p = new CalPoint();
            p.x = ship.x;
            p.y = ship.y;
            ShipsList.add(p);
        }
    }

    /**
     * 保存抽样船数据
     * 保存船舶当前位置数据
     *
     * @param ShipsList 船舶名单
     * @param ships     船只
     */
    public void SaveSamplingShipData(
            ArrayList<CalPoint> ShipsList,
            List<ShipSampling> ships
    ) {
        ShipsList.clear();
        for (int i = 0; i < ships.size(); i++) {
            ShipSampling ship = ships.get(i);
            CalPoint p = new CalPoint();
            p.x = ship.x;
            p.y = ship.y;
            ShipsList.add(p);
        }
    }

    /**
     * 保存队列转换船舶数据
     *
     * @param ShipsList 船舶名单
     * @param Ships     船只
     */
    public void SaveTransShipData(
            Ship[][] Ships,
            ArrayList<CalPoint> ShipsList
    ) {
        ShipsList.clear();
        for (int i = 1; i < Ships.length; i++) {
            CalPoint p = new CalPoint();
            p.x = Ships[i][0].x;
            p.y = Ships[i][0].y;
            ShipsList.add(p);
        }
    }

    /**
     * 保存所有数据
     * @param transformationExample 转换示例Service类，用于读取该类中的计算数据
     * @param time                  时间
     */
    public void SaveAllData(FirstOrderStaticTargetsService transformationExample, double time) {
        //保存目标队列当前位置
        this.ChangeTargetsToPointList(
                transformationExample.target.targets,
                TargetList
        );
        //保存目标队列中心点
        this.ChangeTargetToCenter(
                transformationExample.target,
                Center
        );
        //保存船队当前位置
        this.SaveShipData(
                ShipsList,
                transformationExample.ship.ships
        );
        //保存历史轨迹
        this.SaveHistoryData(
                transformationExample.ship.ships,
                time,
                HistoricalShipsList
        );
    }

    /**
     * 保存所有数据
     * @param firstOrderMovingTargetsCalculate 转换示例Service类，用于读取该类中的计算数据
     * @param time                  时间
     */
    public void SaveAllData(FirstOrderMovingTargetsService firstOrderMovingTargetsCalculate, double time) {
        //保存目标队列当前位置
        this.ChangeTargetsToPointList(
                firstOrderMovingTargetsCalculate.target.targets,
                TargetList
        );
        //保存目标队列中心点
        this.ChangeTargetToCenter(
                firstOrderMovingTargetsCalculate.target,
                Center
        );
        //保存历史轨迹
        this.SaveHistoryData(
                firstOrderMovingTargetsCalculate.ship.ships,
                time,
                HistoricalShipsList
        );
        //保存船队当前位置
        this.SaveShipData(
                ShipsList,
                firstOrderMovingTargetsCalculate.ship.ships
        );
    }


    /**
     * 保存所有数据
     *
     * @param firstOrderAdaptStaticService 一阶适应静态服务
     * @param time                         时间
     */
    public void SaveAllData(FirstOrderAdaptStaticTargetsService firstOrderAdaptStaticService, double time) {
        //保存目标队列当前位置
        this.ChangeTargetsToPointList(
                firstOrderAdaptStaticService.target.targets,
                TargetList
        );
        //保存目标队列中心点
        this.ChangeTargetToCenter(
                firstOrderAdaptStaticService.target,
                Center
        );
        //保存历史轨迹
        this.SaveHistoryData(
                firstOrderAdaptStaticService.ship.ships,
                time,
                HistoricalShipsList
        );
        //保存虚拟目标当前位置
//        this.SaveVirtualTargets(
//                VirtualTargets,
//                firstOrderAdaptStaticService.target.virtualTargets
//        );
    }

    public void SaveVirtualTargets(
            ArrayList<CalPoint> VirtualTargetsList,
            ArrayList<Target> virtualTargets
    ) {
        VirtualTargetsList.clear();
        for (Target tt : virtualTargets) {
            CalPoint p = new CalPoint();
            p.x = tt.x;
            p.y = tt.y;
            VirtualTargetsList.add(p);
        }
    }


    /**
     * 保存所有数据
     *
     * @param firstOrderAdaptMovingTargetsService 一阶适应静态服务
     * @param time                         时间
     */
    public void SaveAllData(FirstOrderAdaptMovingTargetsService firstOrderAdaptMovingTargetsService, double time) {
        //保存目标队列当前位置
        this.ChangeTargetsToPointList(
                firstOrderAdaptMovingTargetsService.target.targets,
                TargetList
        );
        //保存目标队列中心点
        this.ChangeTargetToCenter(
                firstOrderAdaptMovingTargetsService.target,
                Center
        );
        //保存历史轨迹
        this.SaveHistoryData(
                firstOrderAdaptMovingTargetsService.ship.ships,
                time,
                HistoricalShipsList
        );
        //保存船队当前位置
        this.SaveShipData(
                ShipsList,
                firstOrderAdaptMovingTargetsService.ship.ships
        );
    }

    /**
     * 保存所有数据
     * @param secondOrderStaticTarget 读取该类中的计算数据
     * @param time                  时间
     */
    public void SaveAllData(SecondOrderStaticTargetService secondOrderStaticTarget, double time) {
        //保存目标队列当前位置
        this.ChangeTargetSecondToPointList(
                secondOrderStaticTarget.target.targets,
                TargetList
        );
        //保存目标队列中心点
        this.ChangeSecondTargetToCenter(
                secondOrderStaticTarget.target,
                Center
        );
        //保存历史轨迹
        this.SaveSecondHistoryData(
                secondOrderStaticTarget.shipSecond.ships,
                time,
                HistoricalShipsList
        );
        //保存船队当前位置
        this.SaveSecondShipData(
                ShipsList,
                secondOrderStaticTarget.shipSecond.ships
        );
    }


    public List<Double> getShipMinDis() { return shipMinDis; }

    public List<Double> getShipEvDis() {
        return shipEvDis;
    }

    public void setShipMinDis(List<Double> shipMinDis) {
        this.shipMinDis = shipMinDis;
    }

    public void setShipEvDis(List<Double> shipEvDis) {
        this.shipEvDis = shipEvDis;
    }

    /**
     * 保存图表数据
     *
     * @param transformService 转换服务
     */
    public void SaveChartData(TransformService transformService) {

        Ship[][] ships = transformService.tMat.SE;

        double minDis = 100;
        double sumDis = 0;
        double num = 0;
        for (int i = 1; i <= ships.length - 1; i++) {
            for (int j = 1; j < i; j++) {
                double a = transformService.path.Getdistance(ships[i][0], ships[j][0]);
                sumDis += a;
                num++;
                if (a < minDis && a != 0) {
                    minDis = a;
                }
            }
        }
        shipMinDis.add(minDis);
        shipEvDis.add(sumDis / num);
    }

    /**
     * 保存所有数据
     *
     * @param transformService 队列转换服务
     * @param time             时间
     */
    public void SaveAllData(TransformService transformService, double time) {
        //保存历史轨迹
        this.SaveTransHistoryData(
                transformService.tMat.SE,
                time,
                HistoricalShipsList
        );
        //保存船队当前位置
        this.SaveTransShipData(
                transformService.tMat.SE,
                ShipsList
        );
        // 保存平均值等图表数据
        this.SaveChartData(transformService);
    }




    /**
     * 保存所有数据
     * @param intermittentCommunicationService 间歇通信Service类，用于读取该类中的计算数据
     * @param time                  时间
     */
    public void SaveAllData(IntermittentCommunicationService intermittentCommunicationService, double time) {
        //保存目标队列当前位置
        this.SaveLeaderData(
                intermittentCommunicationService.shipController.baseShips.get(0),
                TargetList
        );
        //保存船队当前位置
        this.SaveShipData(
                ShipsList,
                intermittentCommunicationService.shipController.baseShips
        );
        //保存历史轨迹
        this.SaveHistoryData(
                intermittentCommunicationService.shipController.baseShips,
                time,
                HistoricalShipsList
        );
    }


    /**
     * 保存所有数据
     *
     * @param firstOrderNumberRangeTargets 第一个订单号范围目标
     * @param time                         时间
     *///
    public void SaveAllData(FirstOrderNumberRangeTargets firstOrderNumberRangeTargets, double time) {
        //保存目标队列当前位置
        this.ChangeTargetsToPointList(
                firstOrderNumberRangeTargets.target.targets,
                TargetList
        );
//        保存目标队列中心点
        this.ChangeTargetToCenter(
                firstOrderNumberRangeTargets.target,
                Center
        );
//        保存历史轨迹
        this.SaveSamplingHistoryData(
                firstOrderNumberRangeTargets.shipSampling.ships,
                time,
                HistoricalShipsList
        );
//        保存船队当前位置
        this.SaveSamplingShipData(
                ShipsList,
                firstOrderNumberRangeTargets.shipSampling.ships
        );
        this.SaveVirtualTargets(
                VirtualTargets,
                firstOrderNumberRangeTargets.target.virtualTargets
        );
    }

    /**
     * 保存图表数据
     *
     * @param firstOrderNumberRangeTargets 转换服务
     */
    public void SaveChartData(FirstOrderNumberRangeTargets firstOrderNumberRangeTargets) {
        surround.add(
                CheckSurround.Surround(
                        Model.check_inside_util.ParamChangeUtil.TargetsToPoints(firstOrderNumberRangeTargets.target.virtualTargets),
                        Model.check_inside_util.ParamChangeUtil.TargetsToPoints(firstOrderNumberRangeTargets.target.targets))
        );
    }


    /**
     * 保存所有数据
     *
     * @param firstOrderNumberRangeTargets 第一个订单号范围目标
     * @param time                         时间
     *///
    public void SaveAllData(FirstOrderNumberRangeMovingTargets firstOrderNumberRangeTargets, double time) {
        //保存目标队列当前位置
        this.ChangeTargetsToPointList(
                firstOrderNumberRangeTargets.target.virtualTargets,
                TargetList
        );
//        //保存目标队列中心点
        this.ChangeTargetToCenter(
                firstOrderNumberRangeTargets.target,
                Center
        );
//        //保存历史轨迹
        this.SaveSamplingHistoryData(
                firstOrderNumberRangeTargets.shipSampling.ships,
                time,
                HistoricalShipsList
        );
        //保存船队当前位置
        this.SaveSamplingShipData(
                ShipsList,
                firstOrderNumberRangeTargets.shipSampling.ships
        );
        this.SaveVirtualTargets(
                VirtualTargets,
                firstOrderNumberRangeTargets.target.virtualTargets
        );
    }

    public static void setSurround(List<Double> surround) {
        ParamChangeUtil.surround = surround;
    }

    /**
     * 保存图表数据
     *
     * @param firstOrderNumberRangeMovingTargets 转换服务
     */
    public void SaveChartData(FirstOrderNumberRangeMovingTargets firstOrderNumberRangeMovingTargets) {

        double Surround =  CheckSurround.Surround(
                Model.check_inside_util.ParamChangeUtil.TargetsToPoints(firstOrderNumberRangeMovingTargets.target.virtualTargets),
                Model.check_inside_util.ParamChangeUtil.TargetsToPoints(firstOrderNumberRangeMovingTargets.target.targets));
        System.out.println("添加进的SURROUND:" + Surround);
        surround.add(Surround);

    }


}
